前言

@Repeatable是JDK1.8出现的元注解,在早前的版本中声明的注解Annotation是不能够重复作用在同一个类或方法上的,而有些时候我们的开发偏偏需要这样的使用诉求和场景。

使用

单一注解的使用方式如下:

1
2
3
4
5
6
7
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Token {
String optype() default "";
String[] field() default {};
}

引入@Repeatable注解后,改造如下:

1
2
3
4
5
6
7
8
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Tokens.class) // 这里作用在业务注解上
public @interface Token {
String optype() default "";
String[] field() default {};
}

引入了@Tokens返回@Token数组以支持@Token多次注解重复使用

1
2
3
4
5
6
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Tokens {
Token[] value();
}

AOP切面应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Aspect
@Component
public class TokenAspect {
@Pointcut("@annotation(club.hdqyf.springboot.customannotation.annotation.Token)"
+ " || @annotation(club.hdqyf.springboot.customannotation.annotation.Tokens)")
public void annotationPointcut() {
}

@AfterReturning(pointcut = "annotationPointcut()", returning = "rvt")
public void doAfterReturning(JoinPoint joinPoint, Object rvt) throws InvocationTargetException, IllegalAccessException {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Token[] tokens = methodSignature.getMethod().getAnnotationsByType(Token.class);
for (Token declaredAnnotation : tokens) {
// 获取注解上的参数
String[] s = declaredAnnotation.field();
String optype = declaredAnnotation.optype();
// 对应业务...
}
}
}

测试方法

1
2
3
4
5
6
7
8
9
10
@RestController("/")
public class TokenController {
@Token(optype = "html", field = {"content"})
@Token(optype = "text", field = {"text"})
@GetMapping(value = "checkToken")
public TokenVo checkToken(@RequestParam String token) {
TokenVo result = new TokenVo();
return result;
}
}

使用总结

拦截注解 使用注解个数 getAnnotation getAnnotationsByType
@Aop 单个
@Aop 多个 × ×
@Aops 单个 × ×
@Aops 多个 ×
@Aop + @Aops 单个
@Aop + @Aops 多个 ×
  • 使用的时候,为了支持单个和多个的可扩展性,@Around配置同时拦截@Aop和@Aops,通过getAnnotationsByType获取注解数组来获取注解对象进行逻辑操作

  • 通过getAnnotationsByType获取到的 Annotation[] 注解数组也是按照方法的存放顺序由上到下存储的,是有顺序性的,比如按照@Aop(“a”)、@Aop(“c”)、@Aop(“b”)进行配置,则拿到a、c、b的Annotation对象

  • 业务方法被多个相同注解使用,只在一个Aspect切面中使用一次,也就是说Service方法执行一次,Aspect只拦截一次,不会因为多个注解而拦截多次,这是和不同注解作用于一个方法不同

img

ps:因作者能力有限,有错误的地方请见谅

  • 喜欢这篇文章的话可以用快捷键 Ctrl + D 来收藏本页

最后更新: 2022年12月05日 09:41

原始链接: https://blog.hdqyf.club/2022/12/05/20221205-Java 8 多重注解的使用/

× 请我吃糖~
打赏二维码